package com.hwy.chart.component

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Path
import android.graphics.RectF
import com.hwy.chart.BaseChartView
import kotlin.math.max

/**
 * =======================================
 * 作者: hewenyu
 * 日期: 2022/5/11 19:50
 * 说明: 折线图组件，两条图形
 * =======================================
 */
open class DoubleLineChartComponent<T>(chartView: BaseChartView) :
    LineChartComponent<T>(chartView) where T : Number, T : Comparable<T> {

    /**
     * 第二条折线的颜色
     */
    var secondLineColor = Color.GREEN

    /**
     * 第二条折线的宽度
     */
    var secondLineWidth = 2F

    /**
     * 第二条折线的数据集
     */
    private var secondDataList: ArrayList<T?> = ArrayList()

    /**
     * 第二条折线的path
     */
    private val secondLinePath by lazy {
        Path()
    }

    /**
     * 记录第二条折线的封闭path，配合 [shaderPath] 可以计算出两条折线的异或区域
     */
    private val secondShaderPath by lazy {
        Path()
    }

    /**
     * 更新第二条折线的数据集
     */
    fun updateComponentSecondDataList(list: ArrayList<T?>?) {
        secondDataList.clear()
        list?.run {
            secondDataList.addAll(this)
            secondDataList.forEach {
                updateThreshold(it)
            }
        }
    }

    override fun drawFocus(canvas: Canvas, bounds: RectF) {
        if (!isShow) {
            return
        }
        cursorIndex?.let { index ->
            if (index >= 0 && index < dataList.size) {
                componentFocus?.run {
                    // 计算交点坐标
                    val xCoordinate = calculateXCoordinate(index, bounds)
                    var yCoordinate = calculateYCoordinate(index, dataList[index], bounds)
                    // 绘制第一条线的交点
                    strokeColor = lineColor
                    draw(canvas, bounds, xCoordinate, yCoordinate)

                    // 绘制第二条线的交点
                    strokeColor = secondLineColor
                    yCoordinate = calculateYCoordinate(index, secondDataList[index], bounds)
                    draw(canvas, bounds, xCoordinate, yCoordinate)
                }
            }
        }
    }

    override fun drawComponent(canvas: Canvas, bounds: RectF) {
        if (isDataChange()) {
            val count = calculateLinePath(linePath, dataList, bounds)
            val secondCount = calculateLinePath(secondLinePath, secondDataList, bounds)
            dataOffset = max(max(count, secondCount), dataOffset)
        }
        updateAxisDataOffset(dataOffset)
        if (dataOffset > 0) {
            drawShadow(canvas, bounds)
        }
        linePaint.run {
            color = lineColor
            strokeWidth = lineWidth
        }
        drawLinePath(canvas, linePath, linePaint)
        linePaint.run {
            color = secondLineColor
            strokeWidth = secondLineWidth
        }
        drawLinePath(canvas, secondLinePath, linePaint)
    }

    override fun drawShadow(canvas: Canvas, bounds: RectF) {
        if (!isDrawShadow) {
            return
        }

        shaderGradient?.run {
            shaderMatrix.setScale(1F, bounds.height())
            setLocalMatrix(shaderMatrix)
            shaderPaint.shader = this

            // 拷贝第一条曲线
            shaderPath.reset()
            shaderPath.set(linePath)
            shaderPath.lineTo(lastPointF.x, bounds.bottom)
            shaderPath.lineTo(bounds.left, bounds.bottom)
            // 拷贝第二条曲线
            secondShaderPath.reset()
            secondShaderPath.set(secondLinePath)
            secondShaderPath.lineTo(lastPointF.x, bounds.bottom)
            secondShaderPath.lineTo(bounds.left, bounds.bottom)
            // 取两条曲线异或的区域
            shaderPath.op(secondShaderPath, Path.Op.XOR)

            canvas.drawPath(shaderPath, shaderPaint)
        }
    }

}